package com.niiwoo.civet.user.service.local;

import com.alibaba.fastjson.JSON;
import com.niiwoo.civet.user.dao.entity.UserCreditInfo;
import com.niiwoo.civet.user.dao.entity.UserCreditProcess;
import com.niiwoo.civet.user.dto.request.TCCreditAginstFakeCallbackDTO;
import com.niiwoo.civet.user.dto.request.TCCreditCallbackDTO;
import com.niiwoo.civet.user.enums.CreditEnum;
import com.niiwoo.tripod.service.component.SnowflakeIdWorker;
import com.niiwoo.tripod.tiancheng.component.TianchengAgainstFakeV2Service;
import com.niiwoo.tripod.tiancheng.enums.AgainstFakeErrorCodeEnum;
import com.niiwoo.tripod.tiancheng.enums.FunctionCodeEnum;
import com.niiwoo.tripod.tiancheng.request.afp.SpeedLoanCreditAgainstFakeRequest;
import com.niiwoo.tripod.tiancheng.request.afp.SpeedLoanCreditAmountRequest;
import java.util.Date;
import java.util.concurrent.CompletableFuture;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Description: 新授信反欺诈模型，暂未用
 * @Author:LiJian
 * @Date:2017/11/7
 */
@Slf4j
@Service
public class UserCreditV2Service {

    // 天秤授信反欺诈回调地址模型(RCE)
    public static final String TIANCHENG_RCE_CALLBACK_URL = "%s/tc/againstFakeV2/callback?functionCode=%s";

    @Value(value = "${web-http-url}")
    private String webHttpUrl;

    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;

    @Autowired
    private TianchengAgainstFakeV2Service againstFakeV2Service;

    @Autowired
    private TianchengDataService tianchengDataService;

    @Autowired
    private UserCreditService userCreditService;

    /**
     * 创建天秤RCE回调地址
     * @param functionCodeEnum
     * @return
     */
    private String createRCECallbackUrl(FunctionCodeEnum functionCodeEnum) {
        String methodUrl = String.format(TIANCHENG_RCE_CALLBACK_URL, webHttpUrl, functionCodeEnum.getHeadFunctionCode());
        return methodUrl;
    }

    /**
     * 发起天秤极速借授信反欺诈
     * @param userId
     * @param oldUser 0:false  1:true 老用户定义：当前至少有一笔已结清的极速借借款
     */
    private boolean callTCSpeedCreditAgainstFake(String userId, Integer oldUser){
//        SpeedLoanCreditAgainstFakeRequest creditAgainstFakeRequest = new SpeedLoanCreditAgainstFakeRequest();
//        String orderId = String.valueOf(snowflakeIdWorker.nextId());
//        creditAgainstFakeRequest.setTransNo(orderId);
//        creditAgainstFakeRequest.setOrder_id(orderId);
//        creditAgainstFakeRequest.setTransDate(new Date());
//        creditAgainstFakeRequest.setReserve(String.valueOf(userId)); // 保留关键字用userId
//        creditAgainstFakeRequest.setBasic_info(tianchengDataService.getTCBasicInfo(userId));
//        creditAgainstFakeRequest.setNotify_url(this.createRCECallbackUrl(FunctionCodeEnum.LIBRA_FRAUD_SPEED_LOAN_CREDIT));
//        creditAgainstFakeRequest.setOld_user(oldUser);
//        log.info("发起天秤极速借授信发欺诈, userId:{}, params:{}", userId, JSON.toJSONString(creditAgainstFakeRequest));
//        AgainstFakeV2Response againstFakeV2Response = null;
//        try {
//            CompletableFuture<AgainstFakeV2Response> responseCompletableFuture = againstFakeV2Service.speedLoanCreditAgainstFake(creditAgainstFakeRequest);
//            againstFakeV2Response = responseCompletableFuture.get();
//        } catch (Exception e) {
//            log.error("发起天秤极速借授信发欺诈失败, userId:{}, params:{}, errMsg:{}", userId, JSON.toJSONString(creditAgainstFakeRequest), e);
//            return false;
//        }
//        if(AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() != againstFakeV2Response.getCode()) {
//            log.error("天秤极速借授信发欺诈返回失败, userId:{}, params:{}, result:{}", userId, JSON.toJSONString(creditAgainstFakeRequest), JSON.toJSONString(againstFakeV2Response));
//            return false;
//        }
        return true;
    }

    /**
     * 发起天秤极速借授信
     * @param userId
     * @param multiLoan 满足再次借款准入条件 0:false  1:true
     */
    private boolean callTCSpeedCredit(String userId, Integer multiLoan){
//        SpeedLoanCreditAmountRequest creditAmountRequest = new SpeedLoanCreditAmountRequest();
//        String orderId = String.valueOf(snowflakeIdWorker.nextId());
//        creditAmountRequest.setTransNo(orderId);
//        creditAmountRequest.setOrder_id(orderId);
//        creditAmountRequest.setTransDate(new Date());
//        creditAmountRequest.setReserve(String.valueOf(userId)); // 保留关键字用userId
//        creditAmountRequest.setBasic_info(tianchengDataService.getTCBasicInfo(userId));
////        creditAmountRequest.setSocial_security_info(tianchengDataService.getTCSocialSecurityInfo(userId));
//        creditAmountRequest.setNotify_url(this.createRCECallbackUrl(FunctionCodeEnum.LIBRA_CREDIT_SPEED_LOAN));
//        creditAmountRequest.setMulti_loan(multiLoan);
//        log.info("发起天秤极速借授信, userId:{}, params:{}", userId, JSON.toJSONString(creditAmountRequest));
//        AgainstFakeV2Response againstFakeV2Response = null;
//        try {
//            CompletableFuture<AgainstFakeV2Response> responseCompletableFuture = againstFakeV2Service.speedLoanCreditAmount(creditAmountRequest);
//            againstFakeV2Response = responseCompletableFuture.get();
//        } catch (Exception e) {
//            log.error("发起天秤极速借授信失败, userId:{}, params:{}, errMsg:{}", userId, JSON.toJSONString(creditAmountRequest), e);
//            return false;
//        }
//        if(AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() != againstFakeV2Response.getCode()) {
//            log.error("天秤极速借授信返回失败, userId:{}, params:{}, result:{}", userId, JSON.toJSONString(creditAmountRequest), JSON.toJSONString(againstFakeV2Response));
//            return false;
//        }
        return true;
    }

    /**
     * 极速借反欺诈回调本地处理
     * @param creditAginstFakeCallbackDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void speedLoanCreditAgainstFakeLocalHandle(TCCreditAginstFakeCallbackDTO creditAginstFakeCallbackDTO, boolean multiLoan) {
        String userId = creditAginstFakeCallbackDTO.getUserId();
        UserCreditProcess userCreditProcess = new UserCreditProcess();
        userCreditProcess.setUserId(userId);
        userCreditProcess.setCreditType((byte) CreditEnum.CreditAmountType.SPEED_BORROW.getType());
        if(AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() == creditAginstFakeCallbackDTO.getStatus()) {
            // 发起授信
            boolean callStatus = this.callTCSpeedCredit(userId, multiLoan ? 1 : 0);
            Integer status = creditAginstFakeCallbackDTO.getDecision();
            if(status == 0) {
                userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.ACCEPT.getType());
            }else if(status == 2) {
                userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.REVIEW.getType());
            }else {
                userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.REFUSE.getType());
            }
            userCreditProcess.setCreditStatus((callStatus ? CreditEnum.CreditStatus.CALLBACKING.getType() : CreditEnum.CreditStatus.FAIL.getType()));
        }else {
            userCreditProcess.setCreditEndTime(new Date());
            userCreditProcess.setAntifraudStatus(CreditEnum.AntiFraudStatus.FAIL.getType());
        }
        // 修改授信反欺诈及授信过程状态
        userCreditService.updateUserCreditProcess(userCreditProcess);
    }

    /**
     *  极速借授信回调本地处理
     * @param creditCallbackDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void speedLoanCreditLocalHandle(TCCreditCallbackDTO creditCallbackDTO) {
        String userId = creditCallbackDTO.getUserId();
        UserCreditProcess userCreditProcess = new UserCreditProcess();
        userCreditProcess.setUserId(userId);
        userCreditProcess.setCreditType(CreditEnum.CreditAmountType.SPEED_BORROW.getType());
        if(AgainstFakeErrorCodeEnum.SUCCESS.getErrorCode() == creditCallbackDTO.getStatus()) {
            // 更新授信额度信息
            UserCreditInfo userCreditInfo = new UserCreditInfo();
            userCreditInfo.setUserId(userId);
            userCreditInfo.setNeedUpdate(CreditEnum.NeedUpdateStatus.NO.getType());
            userCreditInfo.setCreditType(CreditEnum.CreditAmountType.SPEED_BORROW.getType());
            userCreditInfo.setCreditAmount(creditCallbackDTO.getCreditAmount());
            userCreditInfo.setCreditModelType(creditCallbackDTO.getModelType().byteValue());
            userCreditInfo.setCreditTime(new Date());
            userCreditService.updateUserCreditInfo(userCreditInfo);
        }else {
            userCreditProcess.setCreditEndTime(new Date());
            userCreditProcess.setCreditStatus(CreditEnum.CreditStatus.FAIL.getType());
        }
        // 修改授信反欺诈及授信过程状态
        userCreditService.updateUserCreditProcess(userCreditProcess);
    }
}
